package cn.fsd.service;

import cn.fsd.config.BaiduConfig;
import cn.fsd.vo.LocationPoint;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class BaiduService {

    @Autowired
    BaiduApiService baiduApiService;

    @Autowired
    BaiduConfig baiduConfig;

    //用户可通过该功能，将结构化地址（省/市/区/街道/门牌号）解析为对应的位置坐标。地址结构越完整，地址内容越准确，解析的坐标精度越高。
    public double[] getGeoByAddress(String address) {
        String url = baiduConfig.getWebUrl()+"geocoding/v3/";
        Map<String, Object> param = MapUtil.builder(new HashMap<String, Object>())
                .put("address", address)
                .put("output", "json").build(); //返回json格式的数据
        return baiduApiService.execute(url, Method.GET, param, response -> {
            if(response.isOk()){
                String body = response.body();
                JSONObject jsonObject = JSONUtil.parseObj(body);
                if(jsonObject.getInt("status")!=0){
                    //出错了
                    return null;
                }
                JSONObject location = jsonObject.getJSONObject("result").getJSONObject("location");
                return new double[]{location.getDouble("lng"),location.getDouble("lat")};
            }
            return null;
        });
    }

    //用户可通过该服务，根据起点和终点坐标计算路线规划距离和行驶时间
    public double[] getDistenceAndTime(String origins, String destinations) {//格式：纬度,经度。示例：40.056878,116.30815|40.063597,116.364973
        String url = baiduConfig.getWebUrl()+"routematrix/v2/driving";
        Map<String, Object> param = MapUtil.builder(new HashMap<String, Object>())
                .put("origins", origins)
                .put("destinations", destinations)
                .put("output", "json").build(); //返回json格式的数据
        return baiduApiService.execute(url, Method.GET, param, response -> {
            if(response.isOk()){
                String body = response.body();
                JSONObject jsonObject = JSONUtil.parseObj(body);
                if(jsonObject.getInt("status")!=0){
                    //出错了
                    return null;
                }
                JSONObject result = jsonObject.getJSONArray("result").getJSONObject(0);
                return new double[]{result.getJSONObject("distance").getDouble("value"),
                                    result.getJSONObject("duration").getDouble("value")};
            }
            return null;
        });
    }

    //用户可通过驾车路线规划(非轻量)，根据起点和终点坐标进行路线规划，支持一次请求返回多条路线，返回结果为包括一系列点的经纬度的数组
    //内层List<LocationPoint>表示一条路径，外层List表示所有路径
    public List<List<LocationPoint>> getRoute(String origin, String destination, String waypoints) {//格式：纬度,经度。示例：40.056878,116.30815|40.063597,116.364973
        String url = baiduConfig.getWebUrl()+"direction/v2/driving";
        int flag = 1;//设置alternatives
        //*******如果传入途径点，说明处于手动调度过程，返回一条路径即可;否则是自动调度过程，需返回1-3条********
        if(waypoints!=null&&!waypoints.equals("")) flag = 0;
        Map<String, Object> param = MapUtil.builder(new HashMap<String, Object>())
                .put("origin", origin)
                .put("destination", destination)
                //可以为空，多个途径点坐标按顺序以英文竖线符号分隔，示例： 40.465,116.314|40.232,116.352
                .put("waypoints", waypoints)
                .put("alternatives", flag).build(); //返回1-3条路线供选择
        return baiduApiService.execute(url, Method.GET, param, response -> {
            if(response.isOk()){
                String body = response.body();
                JSONObject jsonObject = JSONUtil.parseObj(body);
                if(jsonObject.getInt("status")!=0){
                    //出错了
                    return null;
                }
                JSONArray routes = jsonObject.getJSONObject("result").getJSONArray("routes");
                if(CollUtil.isEmpty(routes)){
                    return null;
                }
                //所有路径的集合
                List<List<LocationPoint>> paths = new ArrayList<>();
                for (Object route : routes) {
                    //foreach中进行强转，routeJSON为JSON类型的一条路径
                    JSONObject routeJSON = (JSONObject)route;
                    //当前路径的分段数据集合
                    JSONArray steps = routeJSON.getJSONArray("steps");
                    if(CollUtil.isEmpty(steps)){
                        //路径为空则直接跳过
                        continue;
                    }
                    List<LocationPoint> path = new ArrayList<>();
                    for (Object step : steps) {
                        //stepJson为JSON类型的当前路径上的一个分段
                        JSONObject stepJson = (JSONObject) step;
                        String pathOfStep = stepJson.getStr("path");
                        //分段中的一系列点对应的经纬度集合
                        String[] points = StrUtil.splitToArray(pathOfStep, ";");
                        for (String point : points) {
                            //point为一个点对应的经纬度
                            String[] LngAndLat = StrUtil.splitToArray(point, ",");
                            LocationPoint locationPoint = new LocationPoint();
                            locationPoint.setLat(LngAndLat[1]);//纬度
                            locationPoint.setLng(LngAndLat[0]);//经度
                            path.add(locationPoint);
                        }
                    }
                    paths.add(path);
                }
                return paths;
            }
            return null;
        });
    }
}
